package com.daikit.daikit4gxt.server.gwtspring;

import java.lang.reflect.Method;

import org.springframework.beans.factory.annotation.Autowired;

import com.daikit.commons.server.AbstractDkErrorProcessor;
import com.daikit.commons.shared.exception.DkException;
import com.daikit.commons.shared.exception.DkWrapperException;


/**
 * Wrapper surrounding RPC method calls to handle exceptions and wrap them if needed in a {@link DkWrapperException} to
 * have them correctly sent back to client.<br>
 * This class has to be available as a bean in spring context.
 *
 * @author tcaselli
 * @version $Revision$ Last modifier: $Author$ Last commit: $Date$
 */
public class GwtRpcMethodWrapper
{

	@Autowired
	private AbstractDkErrorProcessor errorProcessor;

	/**
	 * Surround RPC calls to catch exception and add message in response
	 *
	 * @param target
	 *           the controller object
	 * @param serviceMethod
	 *           the controller RPC method
	 * @param args
	 *           the controller RPC method arguments
	 * @return the controller RPC method returned value (may be void)
	 * @throws DkException
	 */
	public final Object callRpcMethodInternal(final Object target, final Method serviceMethod, final Object[] args) throws DkException
	{
		try
		{
			return callRpcMethod(target, serviceMethod, args);
		}
		catch (final Throwable e)
		{
			throw errorProcessor.processRpcError(e);
		}
	}

	/**
	 * Override this method to provide custom behavior surround RPC calls
	 *
	 * @param target
	 *           the controller object
	 * @param serviceMethod
	 *           the controller RPC method
	 * @param args
	 *           the controller RPC method arguments
	 * @return the controller RPC method returned value (may be void)
	 * @throws Throwable
	 */
	protected Object callRpcMethod(final Object target, final Method serviceMethod, final Object[] args) throws Throwable
	{
		return serviceMethod.invoke(target, args);
	}

}
